﻿using System;
using System.Collections.Generic;
using AccessControl.Contracts.Settings;
using AccessControl.Contracts.Models;
using System.Collections.ObjectModel;
using AccessControl.DataManagers;
using AccessControl.Gateway.Managers;

namespace AccessControl.Gateway.Settings
{
	class EntriesSettings : IEntriesSettings
	{
		#region Fields

		private static EntriesSettings s_Instance = null;
		private ObservableCollection<IEntry> _Items = new ObservableCollection<IEntry>();

		#endregion

		#region Private Constructor

		private EntriesSettings()
		{
			DataManager.Instance.FillList(Items);
		}

		#endregion

		#region Public Properties

		public static EntriesSettings Instance
		{
			get 
			{
				lock (typeof(EntriesSettings))
				{
					if (s_Instance == null)
						s_Instance = new EntriesSettings();

					return s_Instance;
				}
			}
		}

			#endregion

		#region IEntriesSettings Members

		public bool Add(IEntry item)
		{
			if (DataManager.Instance.Add(item))
			{
				/* Add to the entries manager */
				EntriesManager.Instance.Items.Add(item);
				return true;
			}

			return false;
		}

		public bool Update(IEntry item)
		{
			if (DataManager.Instance.Update(item))
			{
				/* Find the matching one in the entries manager */
				for (int i = 0; i < EntriesManager.Instance.Items.Count; ++i)
				{
					if (EntriesManager.Instance.Items[i].Id == item.Id)
					{
						EntriesManager.Instance.Items.RemoveAt(i);
						EntriesManager.Instance.Items.Insert(i, item);
						break;
					}
				}

				/* And in the maps manager */
				foreach (IMap map in MapsManager.Instance.Items)
				{
					foreach (IMapEntry mapEntry in map.Entries)
					{
						if (mapEntry.Id == item.Id)
						{
							mapEntry.Ip = item.Ip;
							mapEntry.Name = item.Name;
							mapEntry.PortNumber = item.PortNumber;
							mapEntry.State = item.State;
							break;
						}
					}
				}

				return true;
			}
			
			return false;
		}

		public bool Delete(IEntry item)
		{
			if (DataManager.Instance.Delete(item))
			{
				/* Find the matching one */
				foreach (IEntry entry in EntriesManager.Instance.Items)
				{
					if (entry.Id == item.Id)
					{
						EntriesManager.Instance.Items.Remove(entry);
						break;
					}
				}

				/* And remove from the maps entries as well */
				foreach (IMap map in MapsManager.Instance.Items)
				{
					foreach (IMapEntry mapEntry in map.Entries)
					{
						if (mapEntry.Id == item.Id)
						{
							map.Entries.Remove(mapEntry);
							break;
						}
					}
				}

				return true;
			}

			return false;
		}

		public IList<IEntry> Items
		{
			get { return _Items; }
		}

		public void Load()
		{
			Items.Clear();
			DataManager.Instance.FillList(Items);
		}

		#endregion
	}
}
